
/*
 * File name: drp.c
 * Description: Implementation for the Data Ring Protection module.
 * This module provides functions to initialize, store, consume, and manage
 * the protection status of data blocks in a fixed-size array.
 * Author: <Your Name>
 * Date: <Creation Date>
 *
 * Note: This file is part of the <Your Project Name> project and is licensed
 * under <Your License Type>.
 */
#include <stdio.h>
#include <string.h>
#include "FreeRTOS.h"
#include "drp.h"


// 创建和初始化 DataRingProtection 实例
DataRingProtection* DataRingProtection_Create(size_t capacity, size_t dataLength) {
    DataRingProtection *drp = pvPortMalloc(sizeof(DataRingProtection));
    if (drp == NULL) return NULL;
    
    drp->blocks = pvPortMalloc(capacity * sizeof(DataBlock));
    if (drp->blocks == NULL) {
        vPortFree(drp);
        return NULL;
    }
    
    for (size_t i = 0; i < capacity; ++i) {
        drp->blocks[i].data = pvPortMalloc(dataLength);
        if (drp->blocks[i].data == NULL) {
            // 如果内存分配失败，释放已分配的内存并返回 NULL
            while (i > 0) {
                vPortFree(drp->blocks[--i].data);
            }
            vPortFree(drp->blocks);
            vPortFree(drp);
            return NULL;
        }
        drp->blocks[i].initialSize = dataLength;
        drp->blocks[i].actualSize = 0;
        drp->blocks[i].is_protected = false;
    }
    
    drp->capacity = capacity;
    drp->protected_count = 0;
    
    return drp;
}
// 销毁 DataRingProtection 实例并释放内存
bool DataRingProtection_Destroy(DataRingProtection *drp) {
    if (drp) {
        vPortFree(drp->blocks);
        vPortFree(drp);
        drp = NULL;  // 重置全局实例指针
        return true;
    }
    return false;
}

// 存储数据并返回存储区域的指针和长度// 存储数据并返回成功与否
bool DataRingProtection_StoreData(DataRingProtection *drp, const uint8_t *srcData, size_t srcLength, uint8_t **storedPointer) {
    if (drp == NULL || srcData == NULL || srcLength == 0) return false;

    for (size_t i = 0; i < drp->capacity; ++i) {
        if (!drp->blocks[i].is_protected) {
            printf("index=%d Storing srcLength=%d, initialSize=%d\n", i, srcLength, drp->blocks[i].initialSize);
            if (srcLength > drp->blocks[i].initialSize) {
                // 如果初始分配的大小不足以存储新数据，重新分配内存
                vPortFree(drp->blocks[i].data);
                uint8_t *newData = pvPortMalloc(srcLength+1);
                if (newData == NULL) {
                    // 处理内存重新分配失败的逻辑
                    return false;
                }
                // 更新 DataBlock 的数据指针和初始大小
                drp->blocks[i].data = newData;
                drp->blocks[i].initialSize = srcLength+1;
                // memcpy(drp->blocks[i].data, srcData, srcLength);
            } else {
                // 如果当前数据块足够大，不需要重新分配内存
                // 直接复制数据
                // memcpy(drp->blocks[i].data, srcData, srcLength);
            }

            memcpy(drp->blocks[i].data, srcData, srcLength);
            // 更新实际数据长度和保护状态
            drp->blocks[i].actualSize = srcLength;
            drp->blocks[i].is_protected = true;
            drp->protected_count++;
            *storedPointer = drp->blocks[i].data;
			printf("storeDate Ok index=%d, actualsize=%d \n", i, drp->blocks[i].actualSize);
            printf("storeDate addr storedPointer=0x%x, data=0x%x\n", *storedPointer, drp->blocks[i].data);
            // printf("storeDate data storedPointer=%s, data=%s\n", *storedPointer, drp->blocks[i].data);


            return true;
        }
    }

    return false; // 没有找到未保护的数据块
}

// 消费数据并将其拷贝到提供的内存中
bool DataRingProtection_ConsumeData(DataRingProtection *drp, uint8_t *pointer, uint8_t *dstData, size_t *dataLength) {
    if (drp == NULL || dstData == NULL || pointer == NULL) {
        return false; // 无效的输入参数
    }

    for (size_t i = 0; i < drp->capacity; ++i) {
        if (drp->blocks[i].is_protected && drp->blocks[i].data == pointer) {
			printf("pointer matched index=%d\n", i);
            // 检查指针是否匹配，并确保数据长度足够
            // if (drp->blocks[i].actualSize == dataLength) {
                // 拷贝数据
                memcpy(dstData, drp->blocks[i].data, drp->blocks[i].actualSize);
                *dataLength = drp->blocks[i].actualSize;
                // 重置数据块状态
                memset(drp->blocks[i].data, 0, drp->blocks[i].initialSize); // 清空数据
                drp->blocks[i].is_protected = false; // 标记为未保护状态
				drp->blocks[i].actualSize = 0;
                drp->protected_count--; // 更新已保护的数据块数量
                return true;
        }
    }
    return false; // 未找到匹配的受保护数据块或指针不匹配
}

// 获取未保护的数据区数量
size_t DataRingProtection_GetFreeSpace(DataRingProtection *drp) {
    return drp->capacity - drp->protected_count;
}

// 获取已保护的数据区数量
size_t DataRingProtection_GetProtectedCount(DataRingProtection *drp) {
    return drp->protected_count;
}

// 清除单条保护区的保护状态
bool DataRingProtection_ClearProtection(DataRingProtection *drp, uint8_t *pointer) {
    for (size_t i = 0; i < drp->capacity; ++i) {
        if (drp->blocks[i].data == pointer && drp->blocks[i].is_protected) {
            drp->blocks[i].is_protected = false;
            drp->protected_count--;
            return true;
        }
    }
    return false;
}

// 重启初始化数据结构区
void DataRingProtection_Reset(DataRingProtection *drp) {
    if (drp) {
        drp->protected_count = 0;
        memset(drp->blocks, 0, drp->capacity * sizeof(DataBlock));
    }
}